/*
 * Copyright (C) 2000-2004 Technical University of Ilmenau, Germany
 *                         Department of Electronic Circuits & Systems
 *
 * You may only use this file according to the terms of the license agreement included
 * within the file LICENSE which is distributed together with the software package.
 *
 * CVS Info:
 * $Author: rummler $
 * $Date: 2004/03/10 20:19:51 $
 * $Revision: 1.1.2.1 $
 * $State: Exp $
 * $RCSfile: TrivialInitializer.java,v $
 *
 */
package elka.isi.operator;

import elka.isi.RWAlgorithm;
import elka.isi.gene.AnimalGene;
import elka.isi.gene.RabbitGene;
import elka.isi.gene.RoeGene;
import elka.isi.gene.WolfGene;
import elka.isi.individual.RabbitBuilder;
import elka.isi.individual.RoeBuilder;
import elka.isi.individual.WolfBuilder;
import org.evolvica.core.*;
import org.evolvica.core.init.AbstractInitializer;
import org.evolvica.util.RandomUtils;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;

/** Trivial initializer example.
 *
 * @author Andreas Rummler
 * @since 0.4.0
 * @version $Revision: 1.1.2.1 $ $Date: 2004/03/10 20:19:51 $
 */
public class RWInitializer extends AbstractInitializer {
	
	

	// define a field string size with a default value
	protected int stringSize = 10;
	protected IIndividualBuilder rabbitBuilder = new RabbitBuilder();
	protected IIndividualBuilder wolfBuilder = new WolfBuilder();
    protected IIndividualBuilder roeBuilder = new RoeBuilder();

    private int wolfSetSize = 1;
	private int rabbitSetSize = 10;
    private int roeSetSize = 5;
    protected int setSize = wolfSetSize + rabbitSetSize + roeSetSize;
	/**
	 * @see org.evolvica.core.init.AbstractInitializer#createGenotype()
	 */
	protected IGenotype createGenotype() {
		throw new UnsupportedOperationException("Wrong method, use creteWolf or createRabbitGenotype");
		// method to create a single genotype, in this case a string
		// with random alphabetic characters of length <stringSize>
//		String s = RandomStringUtils.randomAlphabetic( stringSize );
		// wrap this string in a genotype and return it
//		return new StringGene( s );
	}
	
	// the getter method for the property stringSize
	// without this method it is impossible to access the property
	public int getStringSize() {
		return stringSize;
	}

	// the setter method for the property stringSize
	// this method is used by the GUI to set new values for this property
	// the name of such methods is always "set" + propertyName with the first
	// character uppercase: stringSize -> setStringSize( ... )
	// the same scheme is used in all get-methods
	// this set-method has a special feature in addition: a PropertVetoException
	// is thrown to indicate that someone tried to set an invalid value to this
	// property: the stringSize must always be > 0!
	public void setStringSize( int i ) throws PropertyVetoException {
		if ( i > 0 ) {
			stringSize = i;
		} else {
			throw new PropertyVetoException( "stringSize must be positive!", // an error message that is displayed in the GUI
				new PropertyChangeEvent(
					this, // the sender of this event (always "this")
					"stringSize", // the property that was attempted to be changed
					new Integer( stringSize ), // the old value of the property
					new Integer( i ) // the new value of the property
				)
			);
		}
		
	}
	/* (non-Javadoc)
	 * @see org.evolvica.core.init.AbstractInitializer#createIndividualSet()
	 */
	public IIndividualSet createIndividualSet() {
		IIndividualSet set = new IndividualArray();
		for (int i = 0; i < wolfSetSize; i++) {
			IIndividual individual = wolfBuilder.newIndividual();
			individual.setGenotype( createWolfGenotype() );
			set.add( individual );
		}
		for (int i = 0; i < rabbitSetSize; i++) {
					IIndividual individual = rabbitBuilder.newIndividual();
					individual.setGenotype( createRabbitGenotype() );
					set.add( individual );
				}
        for (int i = 0; i < roeSetSize; i++) {
            IIndividual individual = roeBuilder.newIndividual();
            individual.setGenotype(createRoeGenotype());
            set.add(individual);
        }
        return set;
	}

    private IGenotype createRabbitGenotype() {
        int[] s = RandomUtils.randomIntegerSample(AnimalGene.GENOME_SIZE, RWAlgorithm.MAX_PARAMETER);
		return new RabbitGene( s );
    }

    private IGenotype createRoeGenotype() {
        int[] s = RandomUtils.randomIntegerSample(AnimalGene.GENOME_SIZE, RWAlgorithm.MAX_PARAMETER);
		return new RoeGene( s );
    }

    private IGenotype createWolfGenotype() {
        int[] s = RandomUtils.randomIntegerSample(AnimalGene.GENOME_SIZE, RWAlgorithm.MAX_PARAMETER);
		return new WolfGene( s );
    }

    /**
	 * @return
	 */
	public int getRabbitSetSize() {
		return rabbitSetSize;
	}

	/**
	 * @return
	 */
	public int getWolfSetSize() {
		return wolfSetSize;
	}

    public int getRoeSetSize() {
        return roeSetSize;
    }

    /**
	 * @param i
	 */
	public void setRabbitSetSize(int i) {
		rabbitSetSize = i;
		setSize = wolfSetSize + rabbitSetSize + roeSetSize;
	}

	/**
	 * @param i
	 */
	public void setWolfSetSize(int i) {
		wolfSetSize = i;
		setSize = wolfSetSize + rabbitSetSize + roeSetSize;
	}

    public void setRoeSetSize(int i) {
        roeSetSize = i;
        setSize = wolfSetSize + rabbitSetSize + roeSetSize;
    }
}
